import axios from 'axios'
import { Message, MessageBox } from 'element-ui'
import store from '../store'
import qs from 'qs'
import requestPathReg from './exportRequest'
import { countDownload } from './countDownload'
/*console.log("当前环境变量："+process.env.NODE_ENV)
console.log("当前环境路径："+process.env.VUE_APP_REQ_URL)*/
let reqUrl = process.env.VUE_APP_REQ_URL
let getImgUrl = process.env.VUE_APP_IMG_URL
let request = axios.create({
  baseURL: reqUrl,
  timeout: 360000,
  withCredentials: true,
  headers: {
    'X-Requested-With': 'XMLHttpRequest',
    // 'x-client-id': 'ee6c968f' //生产
    'x-admin-app': 'pc-yunying-platform' //测试
  }
})
request.interceptors.request.use(
  function(config) {
    config.cancelToken = new axios.CancelToken((cancel) =>
      window.__axiosPromiseArr.push({ cancel })
    )

    // config.cancelToken = new request.CancelToken((cancel) =>
    //   window.__axiosPromiseArr.push({ cancel })
    // )
    /*  // 在发送请求之前做些什么 将 token 赋值到请求头
    request.defaults.headers.Authorization = `Bearer ${localStorage.getItem(
      'access_token'
    )}`
    requestFree.defaults.headers.Authorization = `Bearer ${localStorage.getItem(
      'access_token'
    )}`
    let mid = getMid()
    request.defaults.headers.MID = mid*/
    // let MN = JSON.stringify(sessionStorage.getItem('menuName'))
    // let MN
    // let cachedMenusName = sessionStorage.getItem('cachedMenusName')
    // if (cachedMenusName) {
    //   const { openMenus, selectedMenu } = JSON.parse(cachedMenusName)
    //   openMenus.push(selectedMenu + '')
    //   MN = openMenus.join('-')
    // }
    // console.log(MN, encodeURIComponent(MN))
    // refreshSessionStorage().then((res) => {
    // request.defaults.headers.MN = encodeURIComponent(MN, 'UTF-8')
    // })
    // config.url = `${config.url}&timestrap=${new Date()}`
    // config.params = {
    //   timestrap: new Date().getTime()
    // }
    return config
  },
  function(error) {
    // 对请求错误做些什么
    return Promise.reject(error)
  }
)
/* 响应拦截器*/
request.interceptors.response.use(
  (response) => {
    // 根据状态码，做相应操作
    let status = response.status
    switch (status) {
      case 201:
        if (response.data && response.data.message) {
          Message.success({
            dangerouslyUseHTMLString: true,
            message: response.data.message
          })
        } else {
          Message.success('操作成功')
        }
        break
      case 204:
        Message.success('操作成功')
        break
    }
    requestPathReg(response.config.url, response)
    return response
  },
  (error) => {
    requestPathReg(error.response.config.url, error.response)
    if (error.message.includes('timeout')) {
      // 判断请求异常信息中是否含有超时timeout字符串
      Message.error('网络超时')
    }
    // 根据状态码，做相应操作
    let status = error.response.status
    switch (status) {
      case 400:
        //400使用回调
        break
      case 401:
        /*console.log("401")*/
        // 登录超时
        /* console.log(error.response.data.message)*/
        let msg = ''
        if (error.response.data.state === 1001) {
          msg =
            '该账号已在其他同类设备登录，如非本人操作，则密码可能已经被泄露，建议立即更换密码'
        } else {
          msg = '登录失效, 请重新登录'
        }
        alert(msg)
        window.__axiosPromiseArr.forEach((ele, index) => {
          ele.cancel()
          delete window.__axiosPromiseArr[index]
        })
        signOutToLogin()
        break
      case 409:
        /* case 409:
        console.log('409')*/
        //业务异常统一返回格式，此处需要注销，因为不同的页面对409的处理方式不同
        /* Message.error(error.response.data.message)*/
        break
      case 500:
        Message.error('服务器错误!')
        break
      default:
        Message.error('服务器错误!')
        break
    }
    // if (
    //   (error.response.config.url === '/users/curr-user' ||
    //     error.response.config.url === '/dictionaries/all') &&
    //   status !== 401
    // ) {
    //   signOutToLogin()
    // }
    return Promise.reject(error)
  }
)

/*
 *公共请求 301
 * type-请求类型，post/get/put等
 * url-请求地址
 * sucBack-请求成功回调方法
 * errorBack-请求失败回调方法
 */
function pubRequire(type, url, params, sucBack, errorBack) {
  // `data` 是作为请求主体被发送的数据
  //只适用于这些请求方法 'PUT', 'POST', 和 'PATCH'
  let paramsName = 'data' // 默认作为请求主体被发送的数据
  if (type === 'get' || type === 'delete') {
    paramsName = 'params'
  }
  // 有的put请求传递参数需要在url后拼接 params中设置isQueryString为true
  if (type === 'put' && params.isQueryString) {
    paramsName = 'params'
    delete params.isQueryString
  }
  if (params.isJson) {
    paramsName = 'data'
    delete params.isJson
  }
  //设置请求头
  request.defaults.headers.Authorization = `Bearer ${localStorage.getItem(
    'access_token'
  )}`
  let mid = getMid()
  request.defaults.headers.MID = mid
  // 发起请求
  request({
    method: type,
    url: url,
    [paramsName]: params,
    headers: {
      MN: encodeURIComponent(sessionStorage.getItem('menuName'), 'UTF-8')
    },
    paramsSerializer: (params) => {
      return qs.stringify(params, { indices: false }) // 删除时把数组类型参数格式化成字符串
    }
  })
    .then(
      function(response) {
        if (sucBack) {
          if (url.indexOf('userGroup') > -1) {
            sucBack(response.headers)
          } else {
            // 通用导入返回缓存序列号serial
            if (response.headers['serial']) {
              sucBack(response.headers['serial'])
            } else if (sucBack) {
              // 通用默认返回响应的data数据
              sucBack(response.data)
            }
          }
        }
      },
      function(response) {
        let status = response.response.status
        let data = response.response.data
        let headers = response.response.headers
        //只有409的情况，需要页面的callBack单独处理;403登录失败；413上传图片超过20M
        if (
          status === 409 ||
          status === 403 ||
          status === 413 ||
          (status === 400 && data.message)
        ) {
          if (errorBack) {
            errorBack(data, status, headers) //状态码传入回调方法
          } else {
            if (data.message) {
              Message.warning(data.message)
            }
          }
        }
      }
    )
    .catch(function(err) {})
}
//状态码自由处理
let requestFree = axios.create({
  baseURL: reqUrl,
  timeout: 360000,
  withCredentials: true,
  headers: {
    'X-Requested-With': 'XMLHttpRequest',
    'x-admin-app': 'pc-yunying-platform'
  }
})
requestFree.interceptors.request.use(
  function(config) {
    /* let token = localStorage.getItem('access_token')
    // 在发送请求之前做些什么 将 token 赋值到请求头
    requestFree.defaults.headers.Authorization = `Bearer ${localStorage.getItem(
      'access_token'
    )}`
    request.defaults.headers.Authorization = `Bearer ${localStorage.getItem(
      'access_token'
    )}`
    let mid = getMid()
    requestFree.defaults.headers.MID = mid*/
    // let MN = JSON.stringify(sessionStorage.getItem('menuName'))
    // let MN
    // let cachedMenusName = sessionStorage.getItem('cachedMenusName')
    // if (cachedMenusName) {
    //   const { openMenus, selectedMenu } = JSON.parse(cachedMenusName)
    //   openMenus.push(selectedMenu + '')
    //   MN = openMenus.join('-')
    // }
    // console.log(encodeURIComponent(MN))
    return config
  },
  function(error) {
    // 对请求错误做些什么
    return Promise.reject(error)
  }
)
/* 响应拦截器-状态码自由处理*/
requestFree.interceptors.response.use(
  (response) => {
    // 将 token 赋值到请求头
    /* requestFree.defaults.headers.Authorization = `Bearer ${localStorage.getItem(
      'access_token'
    )}`
    request.defaults.headers.Authorization = `Bearer ${localStorage.getItem(
      'access_token'
    )}`
    let mid = vue.$route.query.mId
    requestFree.defaults.headers.MID = mid*/
    requestPathReg(response.config.url, response)
    return response
  },
  (error) => {
    requestPathReg(error.response.config.url, error.response)
    if (error.message.includes('timeout')) {
      // 判断请求异常信息中是否含有超时timeout字符串
      Message.error('网络超时')
    }
    // 根据状态码，做相应操作
    let status = error.response.status
    switch (status) {
      case 401:
        // 登录超时
        let msg = ''
        if (error.response.data.state === 1001) {
          msg =
            '该账号已在其他同类设备登录，如非本人操作，则密码可能已经被泄露，建议立即更换密码'
        } else {
          msg = '登录失效, 请重新登录'
        }
        alert(msg)
        signOutToLogin()
        break
    }
    // 对请求错误做些什么
    return Promise.reject(error)
  }
)

/*
 *公共请求-状态码自由处理
 * type-请求类型，post/get/put等
 * url-请求地址
 * sucBack-请求成功回调方法
 * errorBack-请求失败回调方法
 */
function pubRequireFree(type, url, params, sucBack, errorBack) {
  // `data` 是作为请求主体被发送的数据
  //只适用于这些请求方法 'PUT', 'POST', 和 'PATCH'
  let paramsName = 'data' // 默认作为请求主体被发送的数据
  if (type === 'get' || type === 'delete') {
    paramsName = 'params'
  }
  // 有的put请求传递参数需要在url后拼接 params中设置isQueryString为true
  if (type === 'put' && params.isQueryString) {
    paramsName = 'params'
    delete params.isQueryString
  }
  if (params.isJson) {
    paramsName = 'data'
    delete params.isJson
  }
  //设置请求头
  requestFree.defaults.headers.Authorization = `Bearer ${localStorage.getItem(
    'access_token'
  )}`
  let mid = getMid()
  requestFree.defaults.headers.MID = mid
  // 发起请求
  requestFree({
    method: type,
    url: url,
    [paramsName]: params,
    headers: {
      MN: encodeURIComponent(sessionStorage.getItem('menuName'), 'UTF-8')
    },
    paramsSerializer: (params) => {
      return qs.stringify(params, { indices: false }) // 删除时把数组类型参数格式化成字符串
    }
  })
    .then(
      function(response) {
        if (sucBack) {
          sucBack(response.data)
        }
      },
      function(response) {
        let status = response.response.status
        let data = response.response.data
        //只有409的情况，需要页面的callBack单独处理;403登录失败
        if (status === 401) return
        if (
          status === 409 ||
          status === 403 ||
          status === 413 ||
          (status === 400 && data.message)
        ) {
          if (errorBack) {
            errorBack(data)
          } else {
            if (data.message) {
              Message.warning(data.message)
            }
          }
        }
      }
    )
    .catch(function(err) {})
}
function changeToForm(obj, type = 'array') {
  let formData = new FormData()
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      // 是对象但不是数组
      if (typeof obj[key] === 'object' && !Array.isArray(obj[key])) {
        for (let item in obj[key]) {
          let name = ''
          if (type === 'string') {
            name = key + '.' + item
          } else {
            name = key + '[' + item + ']'
          }
          formData.append(name, obj[key][item])
        }
      } else {
        formData.append(key, obj[key])
      }
    }
  }
  return formData
}

// function getCurPageMenu(id) {
//   let url = `/menus/${id}/childrens`
//   return new Promise((resolve, reject) => {
//     pubRequire(
//       'get',
//       url,
//       '',
//       (response) => {
//         resolve(response)
//       },
//       (response) => {
//         Message({
//           message: '获取权限失败!' + response.msg,
//           type: 'warning'
//         })
//         reject(response)
//       }
//     )
//   })
// }
function alertPower(str) {
  MessageBox(`您没有查看数据的权限，请联系管理员添加权限[${str}]`, '系统提示', {
    confirmButtonText: '确定',
    type: 'warning'
  })
}
/*
 *公共下载文件 301
 * type-请求类型，post/get/put等
 * url-请求地址
 * sucBack-请求成功回调方法
 * errorBack-请求失败回调方法
 */
function downFile(type, url, params, title, errBack, lifeName = '') {
  // 发起请求
  request({
    method: type,
    url: url,
    params: params,
    responseType: 'blob' // 后端返回文件流转为blob
  })
    .then(
      function(response) {
        store.commit('userGroup/updateDeriveState', true)
        let time = new Date().getTime()
        let fileName = `${time}${title}.xlsx`
        // 针对问卷数据、用户分组-标题的处理【author:王超】
        if (
          url.indexOf('questionnaires') > -1 ||
          url.indexOf('userGroup') > -1 ||
          url.indexOf('user-group/export/group/dpaccount') > -1
        ) {
          fileName = `${title}.xlsx`
        }
        if (response.data.type.indexOf('application/zip') > -1) {
          fileName = `${title}.zip`
        }
        let blob = response.data
        const downloadLink = document.createElement('a')
        downloadLink.download = fileName
        downloadLink.href = URL.createObjectURL(blob)
        document.body.appendChild(downloadLink)
        downloadLink.click()
        URL.revokeObjectURL(downloadLink.href)
        document.body.removeChild(downloadLink)
        if (lifeName) {
          store.commit('setExportLoading', { key: lifeName, value: false })
        }
        countDownload(response.data, params)
      },
      async function(response) {
        store.commit('userGroup/updateDeriveState', true)
        let data = response.response.data
        if (data.type === 'application/json') {
          //将数据流转换成字符串
          let text = await data.text()
          //将字符串转换成json
          let jsonText = await JSON.parse(text)
          let message = jsonText.message
          if (errBack) {
            errBack(message)
          } else {
            Message.warning(message)
          }
        }
        if (lifeName) {
          store.commit('setExportLoading', { key: lifeName, value: false })
        }
      }
    )
    .catch(function(response) {
      store.commit('userGroup/updateDeriveState', true)
      if (lifeName) {
        store.commit('setExportLoading', { key: lifeName, value: false })
      }
    })
}
/* 退出 */
function signOutToLogin() {
  store.commit('setUserInfo', null)
  localStorage.setItem('redirectUrl', location.href)
  const local = `${location.protocol}//${location.host}`
  window.top.location.href = `${process.env.VUE_APP_AUTH_URL}/logout?redirectUrl=${local}`
  localStorage.removeItem('access_token')
  localStorage.removeItem('refresh_token')
}

/*获取query mId*/
function getMid() {
  let query = window.location.search.substring(1)
  let reg = /([^?&=]+)=([^?&=]+)/g,
    obj = {}
  query.replace(reg, function() {
    obj[arguments[1]] = arguments[2]
  })
  return obj.mId || ''
}

export {
  pubRequire,
  pubRequireFree,
  changeToForm,
  // getCurPageMenu,
  alertPower,
  request,
  reqUrl,
  getImgUrl,
  downFile,
  signOutToLogin
}
